﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Web.UI;
using System.ComponentModel;
using Terralever.Facebook.UI.Design;

namespace Terralever.Facebook.UI.FbmlControls
{
    /// <summary>
    /// Provides common functionality for the logic test controls, including <see>IsInNetwork</see>, <see>IfCanSee</see>, <see>IfCanSeePhoto</see>, 
    /// <see>IfIsAppUser</see>, <see>IfIsFriendsWithViewer</see>, <see>IfIsGroupMember</see>, <see>IfIsUser</see>, and <see>IfSectionNotAdded</see>.
    /// </summary>
    [ParseChildren(ChildrenAsProperties = true)]
    [PersistChildren(false)]
    [Designer("Terralever.Facebook.UI.Design.FbmlControls.LogicTestControlDesigner, " + Constants.DESIGNER_LIB)]
    public abstract class LogicTestControl : FbmlControl
    {
        private ITemplate m_yesTemplate, m_noTemplate;
        private LogicTestTemplateContainer m_yesContainer, m_noContainer;

        /// <summary>
        /// Gets or sets the template that should be displayed when the test's conditions are met.  This property is required.
        /// </summary>
        [Browsable(false)]
        [PersistenceMode(PersistenceMode.InnerProperty)]
        [DefaultValue(null)]
        [TemplateInstance(TemplateInstance.Single)]
        [TemplateContainer(typeof(LogicTestTemplateContainer))]
        [FbmlRequired(IsRequired = true)]
        public ITemplate IsValidTemplate
        {
            get { return m_yesTemplate; }
            set
            {
                m_yesTemplate = value;
                if (m_yesTemplate != null)
                    CreateContents();
            }
        }

        /// <summary>
        /// Gets or sets the template that should be displayed when the test's conditions are not met.
        /// </summary>
        [Browsable(false)]
        [PersistenceMode(PersistenceMode.InnerProperty)]
        [DefaultValue(null)]
        [TemplateInstance(TemplateInstance.Single)]
        [TemplateContainer(typeof(LogicTestTemplateContainer))]
        public ITemplate IsNotValidTemplate
        {
            get { return m_noTemplate; }
            set
            {
                m_noTemplate = value;
                if (m_noTemplate != null)
                    CreateContents();
            }
        }

        /// <inheritdoc />
        protected override void Render(HtmlTextWriter writer)
        {
            if (m_yesContainer == null)
                throw new RequiredFbmlAttributeNotSetException("The <IsValidTemplate> template is missing and is required.");

            CreateContents();

            AddAttributesToRender(writer);
            writer.RenderBeginTag(ElementName);
            m_yesContainer.RenderControl(writer);
            if (m_noTemplate != null)
            {
                writer.RenderBeginTag(FbmlConstants.FB_ELSE);
                m_noContainer.RenderControl(writer);
                writer.RenderEndTag();
            }
            writer.RenderEndTag();
        }

        private void CreateContents()
        {
            ClearContents();

            if (m_yesContainer == null)
            {
                m_yesContainer = new LogicTestTemplateContainer(this);
                if (m_yesTemplate != null)
                {
                    m_yesTemplate.InstantiateIn(m_yesContainer);
                }
                this.Controls.Add(m_yesContainer);
            }
            else if (m_yesTemplate != null)
            {
                this.m_yesTemplate.InstantiateIn(this.m_yesContainer);
            }

            if (m_noContainer == null)
            {
                m_noContainer = new LogicTestTemplateContainer(this);
                if (m_noTemplate != null)
                    this.m_noTemplate.InstantiateIn(this.m_noContainer);
                Controls.Add(m_noContainer);
            }
            else if (m_noTemplate != null)
            {
                this.m_noTemplate.InstantiateIn(this.m_noContainer);
            }
        }

        internal void ClearContents()
        {
            if (m_yesContainer != null)
                m_yesContainer.Controls.Clear();

            m_yesContainer = null;

            if (m_noContainer != null)
                m_noContainer.Controls.Clear();

            m_noContainer = null;

            Controls.Clear();
        }

        private DesignerDisplayMode m_mode = DesignerDisplayMode.LogicTestPassed;
        /// <summary>
        /// Gets or sets a design-time setting specifying which template to render.
        /// </summary>
        /// <exception cref="InvalidEnumArgumentException">Thrown if <paramref name="value"/> is not a member of the 
        /// <see cref="Terralever.Facebook.UI.Design.DesignerDisplayMode">DesignerDisplayMode</see> enumeration.</exception>
        [Browsable(false)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public DesignerDisplayMode DesignerDisplayMode
        {
            get { return m_mode; }
            set
            {
                if (!Enum.IsDefined(typeof(DesignerDisplayMode), value))
                    throw new InvalidEnumArgumentException("value", (int)value, typeof(DesignerDisplayMode));

                m_mode = value;
            }
        }
    }
}
